<?
/*
Mutable Spam Poison ver. 0.1 Beta 1

This is an open testing version, that may contain serious bugs. Do not use it on critical 
systems!

This software is realesed under the GNU/GPL v2 Licence. 
For more information please visit http://www.gnu.org/copyleft/gpl.html

You can contact the authors by e-mail at blueover [at] gmail [dot] com
Official homepage: http://code.google.com/p/must
*/

/* Global configuration */
$words=file("words.txt");
$ccodes=file("ccodes.txt");
$password="";             // You don't have to remember it so let it be complicated!  
$generator="google";      // Coma separated list of page generators. See the Generators comment section for avalible values!
$network="network.txt";

if (filesize($network)<10) $network=array();
else $network=file($network);

/*Global variables - Don't change them!*/
$key="";

/* Configuration for the Google based generator */
$google_minsize=1;
$google_maxsize=10;

/* Configuration for the other generators ... */

/*Logging the page visits - beta feature remove from stable code!*/
include("logger.php");

/***********************************Genetators****************************************
These functions generate the poisonous pages. Every functions name has to start with
'generator_' and end in its unique name. The only parameter a generator can get is 
the key, generated by the GenerateKey() func. Every other parameters has to be set as
global variables at the top of the file. It is the job of the generators to actually 
create the page, only they can generate output.
If you write a new function please append its unique name  with a short description 
to this list:

google - Generates the pages from existing pages using Google. Needs enabled url fopen!
*************************************************************************************/
function generator_google($k){
  global $words,$google_minsize,$google_maxsize;
  /*Get a "random" word*/
  $ksum=1;
  for($i=0;$i<strlen($k);$i++){
    $ksum*=(ord($k[$i])+1);
    $ksum=$ksum%count($words);
  }
  $ksum=$ksum%count($words);

  $s=$words[($ksum*(ord($k[0])+1)*(ord($k[strlen($k)-1])+1))%count($words)];
  $s=htmlentities(trim($s));

  /*Getting search results*/
  $f=file("http://www.google.com/search?q=$s");
  
  if (!is_array($f))
    die("Can not open URL! Check if allow_url_fopen is enabled!");

  /*Filtering URLs and sizes from results*/  
  foreach($f as $key=>$val){
    $f[$key]=str_replace("\n","",$f[$key]);
    $f[$key]=str_replace("\r","",$f[$key]);
  }

  $h=array();

  foreach($f as $key=>$val){
    $g=split(">",$f[$key]);
    foreach($g as $gkey=>$gval){
      $h[]=$g[$gkey];
    }
  }

  $f=$h;
  unset($h);

  $state=0;
  $urls=array();
  $a=0;
  $matches=array();
  for($i=0;$i<sizeof($f);$i++){
    if($state==0){
      if (strpos($f[$i],'<a class=l')!==FALSE)
      { 
        $urls[$a]['url']=substr($f[$i],17,-1);
        $state=1;
  
      }
    }else{
      if (strpos($f[$i],'k - ')!==FALSE){
        $matches=split(' - ',$f[$i]);
        $urls[$a]['size']=intval(substr($matches[1],0,-1));
  
        $a++;
        $state=0;
      }
    }
  }

  /*Selecting the appropiate page*/
  $page=0;
  foreach($urls as $uk=>$u){
    if (($u['size']<=$google_maxsize && $u['size']>$urls[$page]['size']) || 
        ($u['size']>=$google_minsize && $u['size']<$urls[$page]['size'] && $urls[$page]['size'] > $google_maxsize)){
      $page=$uk;
    }
  }

  /*Got it, now download the page and transform it into a trap!*/
  $trap=file($urls[$page]['url']);
  
  if (!is_array($trap)){
    generator_google($k.'a');
    return;
  }
  foreach($trap as $t){
    $t=preg_replace('/<base ([^<]*)([^>]*)>/i','',$t); // remove evil base URLs
    $pattern='/<a ([^<]*)href=(\"|\')([^\'\"]*)(\"|\')([^>]*)>/i';  //normal links
    preg_match_all($pattern,$t,$regs,PREG_SET_ORDER);
    foreach($regs as $r)
      $t=str_replace($r[3],GenerateLink($r[3]),$t);
      echo $t;
  }
}

/**********************************END OF GENERATORS**************************************
******************************************************************************************/

/* 
This function is called at the begining and every time a link or an e-mail address is 
generated, so an attacker can never get useful information about the original password.

TODO:Itt erdemes bizonyitottan egyiranyu algoritmust hasznalni, mivel
ha valaki ramozdul egy generalt oldalra, akkor nehezen ugyan,
de elvileg meg birja szerezni a passt! Ellenben jo lenne ha nem kene 10 mp-et varni mire 
kiszamolja a dolgokat...
*/
function GenerateKey($p){
  global $key;  

  $key=md5($p.$_SERVER['REQUEST_URI'].$_SERVER['SERVER_NAME']);
}

/*
This function can generate links to redirect bots to the local poison script
or to other poisonous sites of the network. The function determines if:

- The parameter is an e-mail link (mailto:): calls the GenerateEmail() function, and 
returns a fake e-mail link
- The parameter is a link to a local document (no http:// nor mailto:): Depending on the 
given parameter and the key it returns a link to the local script or to an e-mail 
address.
- The parameter is a regular link to an other site (http://): returns a link to another 
site of the network if there is such, else it acts like in the case of local 
links. 

TODO: This function has to be reviewed. I dont know at this time how much information 
can be retrieved from the output abut the password or the key, adn how dangerous this
information is
*/
function GenerateLink($link){
  global $network,$key; 


  if ((stripos($link,"mailto:")!==FALSE) || ((ord($key[1])%10)<5))
    return "mailto:".GenerateEmail($link);
  elseif ((stripos($link,"http://")!==FALSE) && (count($network)>0) && (ord($key[1])%10<5)){
    return trim($network[GenerateRandom($link,count($network))]);
  }else{
    if ((ord($key[0])%10)<3){
      global $words;
      $param=GenerateRandom($link,count($words));
      $value=GenerateRandom($link,1000);
      return $_SERVER['SCRIPT_NAME']."?".$words[$param][0].$words[$param][strlen($words[$param])-2]."=".$value;
    }else{
      return "mailto:".GenerateEmail($link);
    }
  }  
}

function GenerateEmail($link){
  global $words,$ccodes;

  $user=preg_replace('/[\s]+/','.',trim($words[GenerateRandom($link,count($words))]));
  $host=trim(preg_replace('/[\s]+/','',$words[GenerateRandom($link,count($words))]));
  $country=trim(preg_replace('/[\s]+/','',$ccodes[GenerateRandom($link,count($ccodes))]));
  return $user."@".$host.".".$country;
}
/*
Generates "random" integer from the key and a given seed, and mutates the key.
We don't use true random values, because those can be easyly detected by bots.
*/
function GenerateRandom($seed,$max){
  global $key;
  GenerateKey($key);
  $m=md5($seed.$key);
  $ret=1;

  for ($i=0;$i<32;$i++){
    $ret*=ord($m[$i])+1;
    $ret=($ret%$max)+1;
  }

  return $ret-1; 
}

GenerateKey($password);

$generators=split(",",$generator);
call_user_func("generator_".$generators[GenerateRandom($_SERVER['REQUEST_URI'],count($generators))],$key);

?>
